package cn.jiangjiesheng.bootstrap.gateway.auth;

import cn.hutool.core.collection.ConcurrentHashSet;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import cn.jiangjiesheng.bootstrap.commons.exception.BizzException;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by dev@jiangjiesheng.cn on 2021/9/26  <br/>
 *
 * @author dev@jiangjiesheng.cn
 */
@Service
@Slf4j
public class QPaasAuthService {

    @Autowired
    private AuthFilterProperties authFilterProperties;
//
//    @Autowired
//    private PaasTemplate paasTemplate;

    private static String CACHE_PREFIX = "gateway:accesstoken:";

    @Autowired
    private RedisTemplate<String,JSONObject> redisTemplate;

    private final static ConcurrentHashSet<String> queryingAccessTokens = new ConcurrentHashSet<>();

    private final List<String> upstreamHeaderKeys = Arrays.asList("last_login_enterprise",
            "enterprise_id", "real_name",
            "avatar",
            "pinyin",
            "enterprise_name", "role_name",
            "sex",
            "user_id",
            "phone",
            "access_token"
    );

    private String getCacheKey(String key){
        return CACHE_PREFIX+key;
    }

    public Boolean ifAccessTokenPresentInCache(String accessToken) {
        return Objects.nonNull(redisTemplate.opsForValue().get(getCacheKey(accessToken)));
    }

    public JSONObject qPaasUserInfo(@NonNull String accessToken) {
        accessToken = StringUtils.stripStart(accessToken, "[");
        accessToken = StringUtils.stripEnd(accessToken, "]");
        accessToken = accessToken.replace("access_token=", "");
        JSONObject returning = null;
        //TODO 改用reactive 的等待方式
//        if(queryingAccessTokens.contains(accessToken)){
//            this.qPaasUserInfo(accessToken);
//        }
        if (authFilterProperties.getEnableAccessTokenCache()) {
            // 已启用 accessToken缓存
            returning = redisTemplate.opsForValue().get(getCacheKey(accessToken));
            if (Objects.isNull(returning)) {
                try {
                    queryingAccessTokens.add(accessToken);
                    returning = readingUserInfoFromPaas(accessToken);
                    if (Objects.isNull(returning)) {
                        throw new BizzException("不符合预期，LRU缓存出错");
                    }
                    redisTemplate.opsForValue().set(accessToken, returning);
                } finally {
                    queryingAccessTokens.remove(accessToken);
                }
            }
            return returning;
        } else {
            return readingUserInfoFromPaas(accessToken);
        }
    }

    /**
     * 通过Token获取用户信息
     *
     * @param accessToken
     * @return
     */
    public JSONObject readingUserInfoFromPaas(final String accessToken) {
//        final IamGetUserInfoByIdTokenRequest request = new IamGetUserInfoByIdTokenRequest();
//        request.setAccessToken(accessToken);
//        request.setIdToken("");
//        final PaasTemplate.PaasResult result = paasTemplate.execute(request);
//        Map<String, Object> reqParams = new HashMap<>(1);
//        reqParams.put("accessToken", accessToken);
//        Map<String, Object> returning = result.toRawMap();
        Map<String, Object> returning = Maps.newHashMap();
        returning.keySet().retainAll(upstreamHeaderKeys);
        returning.put("access_token", accessToken);
        return new JSONObject(returning);
    }
}
